package com.huatai.common.httputil;

/**
 * @program: ht-system
 * @description:
 * @author: songxiude
 * @create: 2023-04-25 15:49
 **/

import java.io.IOException;
import java.util.function.Predicate;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.springframework.retry.backoff.FixedBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;

public class RetryInterceptor implements Interceptor {
	private final RetryPolicy retryPolicy;

	public Response intercept(Interceptor.Chain chain) throws IOException {
		Request request = chain.request();
		RetryTemplate template = createRetryTemplate(this.retryPolicy);
		return (Response)template.execute((context) -> {
			Response response = chain.proceed(request);
			Predicate<ResponseSpec> respPredicate = this.retryPolicy.getRespPredicate();
			if (respPredicate == null) {
				return response;
			} else {
				ResponseBody body = response.peekBody(Long.MAX_VALUE);
				HttpResponse httpResponse = new HttpResponse(response);
				Throwable var8 = null;

				try {
					if (respPredicate.test(httpResponse)) {
						throw new IOException("Http Retry ResponsePredicate test Failure.");
					}
				} catch (Throwable var17) {
					var8 = var17;
					throw var17;
				} finally {
					if (httpResponse != null) {
						if (var8 != null) {
							try {
								httpResponse.close();
							} catch (Throwable var16) {
								var8.addSuppressed(var16);
							}
						} else {
							httpResponse.close();
						}
					}

				}

				return response.newBuilder().body(body).build();
			}
		});
	}

	private static RetryTemplate createRetryTemplate(RetryPolicy policy) {
		RetryTemplate template = new RetryTemplate();
		SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
		retryPolicy.setMaxAttempts(policy.getMaxAttempts());
		FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
		backOffPolicy.setBackOffPeriod(policy.getSleepMillis());
		template.setRetryPolicy(retryPolicy);
		template.setBackOffPolicy(backOffPolicy);
		return template;
	}

	public RetryInterceptor(final RetryPolicy retryPolicy) {
		this.retryPolicy = retryPolicy;
	}
}

